#include "functionFitness.h"

int genotype2fenotype(vector<bool> chromosome){
	int x=0;
	unsigned int sizeChrom = chromosome.size();
	for(unsigned int i=0;i<chromosome.size();i++){
		if(chromosome[i]) x += pow(2,sizeChrom-i-1);
	}
	return x;
}
vector<bool> fenotype2genotype(int xa,int sizeChrom){
	vector<bool> chromosome(sizeChrom);
	for (int i=0; i<sizeChrom; i++){
		chromosome[sizeChrom - i-1] = xa % 2;
		xa = int(xa/2);
	}
	return chromosome;
}

bool notin(int x,vector<int>& v){
	for(unsigned int i=0;i<v.size();i++){
		if(x == v[i]) return false;
	}
	return true;
}

int repeat(vector<vector<bool> >& v){
	vector<int> aux; int cont = 0;	
	for(unsigned int i=0;i<v.size();i++){
		int a = genotype2fenotype(v[i]);
		if(notin(a,aux)) aux.push_back(a);
	}
	cont=aux.size();
	return v.size()-cont;
}

int functionFitness(vector<vector<bool> >& vChrom){
	vector<bool> aux; 
	vector<vector<bool> > a;
	aux.resize(4); 
	int cont = 0;
	//--------------------------------------------------------------------------	
	//Horizontal
	for(int g=0;g<3;g++){
		for(int h=0;h<3;h++){
			for(int i=h*3+g*27;i<h*3+27+g*27;i+=9){		
				for(int j=i;j<i+3;j++){
						a.push_back(vChrom[j]);
						//cout<<j<<" ";
				}
			}
			//cout<<endl;
			cont += repeat(a);
			a.clear();
		}
	}
	cont*=1.4; //Penalizo filas
	//cout<<cont; cin.get();
	//Subgrupo
	for(int i=0;i<9;i++){
		for(int j=i*9;j<i*9+9-1;j++){
			aux = vChrom[j];
			for(int k=j+1;k<i*9+9;k++){
				if(vChrom[k] == aux) cont++;
			}
			//cout<<j<<" ";
		}
		//cout<<i*9+8<<endl;
	}
	//cout<<cont; cin.get();
	//Vertical
	int cont1 = 0;
	for(int g=0;g<3;g++){
		for(int h=0;h<3;h++){
			for(unsigned int i=g*9+h;i<vChrom.size();i+=27){		
				for(unsigned int j=i;j<i+9;j+=3){
						a.push_back(vChrom[j]);
						//cout<<j<<" ";
				}
			}
			//cout<<endl;
			cont1 += repeat(a);
			a.clear();
		}
	} 
	cont1*=1.4; //Penalizo columnas
	cont+=cont1;
	//cout<<cont; cin.get();
	return cont; //penalizo
}
